# @Author: 唐奇才
# @Time: 2021/6/8 20:09
# @File: 16.使用K均值对UCI wine数据集进行分析.py
# @Software: PyCharm

from sklearn import datasets
from matplotlib import pyplot as plt
import numpy as np
from sklearn.cluster import KMeans
from sklearn import metrics
from sklearn import preprocessing


# 加载白酒数据
wine = datasets.load_wine()
original_x = wine.data
labels = wine.target
datas = preprocessing.scale(original_x)


np.delete(datas, [0,1,2,3,4,5,7,8,9,10,12], axis=1)

# 设计最大值和最小值作为绘图边缘
border = 0.5

x_min, x_max = datas[:, 0].min() - border, datas[:, 0].max() + border
y_min, y_max = datas[:, 1].min() - border, datas[:, 1].max() + border

# 进行kMeans聚类
kmeans = KMeans(init='k-means++', n_clusters = 3)
kmeans.fit(datas)

"""
inertia_ : float
        The value of the inertia criterion associated with the chosen
        partition (if compute_labels is set to True). The inertia is
        defined as the sum of square distances of samples to their nearest
        neighbor.
        与所选分区关联的惯性标准的值（如果 compute_labels 设置为 True）。惯性定义为样本到其最近邻居的平方距离之和。
Homogeneity metric of a cluster labeling given a ground truth.
给定基本事实的集群标记的同质性度量。
Returns
    -------
    completeness : float
       score between 0.0 and 1.0. 1.0 stands for perfectly complete labeling
得分介于 0.0 和 1.0 之间。 1.0 代表完美完整的标签

The V-measure is the harmonic mean between homogeneity and completeness::

        v = (1 + beta) * homogeneity * completeness
             / (beta * homogeneity + completeness)
"""
print(35 * '_')
print('inertia\thomo\tcompl\tv-meas\t')
print('%i\t%.3f\t%.3f\t%.3f\t'
      % (kmeans.inertia_,
         metrics.homogeneity_score(labels, kmeans.labels_),
         metrics.completeness_score(labels, kmeans.labels_),
         metrics.v_measure_score(labels, kmeans.labels_),
        ))
print(35 * '_')


distances_for_labels = []
for label in range(kmeans.n_clusters):
    distances_for_labels.append([])


for i, data in enumerate(datas):
    label = kmeans.labels_[i]
    center = kmeans.cluster_centers_[label]
    distance = np.sqrt(np.sum(np.power(data - center, 2)))
    distances_for_labels[label].append(distance)
ave_distances = [np.average(distances_for_label) for distances_for_label in distances_for_labels]


fig, ax = plt.subplots()
ax.set_aspect('equal')


#设置坐标范围
ax.set_xlim((x_min, x_max))
ax.set_ylim((y_min, y_max))


#绘制每个Cluster
for label, center in enumerate(kmeans.cluster_centers_):
    radius = ave_distances[label] * 0.6
    ax.add_artist(plt.Circle(center, radius = radius, color = "r", fill = False))


#根据每个数据的真实label来选择数据点的颜色
plt.scatter(datas[:, 0], datas[:, 1], c = wine.target)
plt.show()


